-
Notifications
You must be signed in to change notification settings - Fork 937
DDBEnhanced - Support to flatten a Map into top level attributes of the object #6102
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
DDBEnhanced - Support to flatten a Map into top level attributes of the object #6102
Conversation
25598b0
to
fab983f
Compare
fab983f
to
b0979f4
Compare
"type": "feature", | ||
"category": "Amazon DynamoDB Enhanced Client", | ||
"contributor": "", | ||
"description": "Added the support to flatten a Map into top level attributes of the object" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: mention the annotation name here. Maybe:
Add support for @DynamoDBFlattenMap to flatten a Map to top level attributes of an object
@@ -685,3 +685,53 @@ private static final StaticTableSchema<Customer> CUSTOMER_TABLE_SCHEMA = | |||
``` | |||
Just as for annotations, you can flatten as many different eligible classes as you like using the | |||
builder pattern. | |||
|
|||
#### Using composition |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is already a "Using composition" header above this (so this already falls under that section).
I think ths should be its own ###
level header instead - maybe "### Flattening map attributes"
|
||
#### Using composition | ||
|
||
Using composition, the @DynamoDBFlattenMap annotation support to flatten a Map: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this reads a bit weirdly, consider rephrasing.
public void setDetailsMap(Map<String, String> record) { this.detailsMap = detailsMap;} | ||
} | ||
``` | ||
You can flatten only one map present on a record, otherwise it will be thrown an exception |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
May want to add that this includes maps on any flattened classes as well.
Phrasing nit: "otherwise it will be thrown an exception" -> "otherwise an exception will be thrown".
Additionally - are there other constraints we should mention here? What key and value types are supported? It is only <String, String>?
|
||
@DynamoDbFlattenMap | ||
public Map<String, String> getDetailsMap() { return this.detailsMap; } | ||
public void setDetailsMap(Map<String, String> record) { this.detailsMap = detailsMap;} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
parameter name record
here is incorrect, it should be detailsMap
.
public void setDetailsMap(Map<String, String> record) { this.detailsMap = detailsMap;} | |
public void setDetailsMap(Map<String, String> detailsMap) { this.detailsMap = detailsMap;} |
private Map<String, AttributeValue> itemToMap(T item, boolean ignoreNulls, List<String> attributeNames) { | ||
Map<String, String> mapItem = this.mapItemGetter.apply(item); | ||
|
||
Map<String, AttributeValue> result = new HashMap<>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
white space nit - make sure you've run checkstyle.
Map<String, AttributeValue> result = new HashMap<>(); | |
Map<String, AttributeValue> result = new HashMap<>(); |
.setter(Customer::setName)) | ||
// Because we are flattening a Map object, we supply a getter and setter so the | ||
// mapper knows how to access it | ||
.flattenMap(Map::detailsMap, Map::detailsMap) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.flattenMap(Map::detailsMap, Map::detailsMap) | |
.flattenMap(Map::getDetailsMap, Map::setDetailsMap) |
} | ||
|
||
@Test | ||
public void updateItemWithFlattenMap_withDuplicateAttributeName_throwsIllegalArgumentException() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we also add a similar test for behavior with the FlattenMapAndFlattenRecordBean with a duplicate attribute in the flattened record?
@@ -286,6 +302,15 @@ private static Optional<Method> findFluentSetter(Class<?> beanClass, String prop | |||
.findFirst(); | |||
} | |||
|
|||
private static boolean dynamoDbFlattenMapAnnotationHasInvalidUse(List<PropertyDescriptor> mappableProperties) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry more validation questions - what about cases where multiple traits are applied, eg:
@DynamoDbUpdateBehavior(UpdateBehavior.WRITE_IF_NOT_EXISTS)
@DynamoDbFlattenMap
public Map<String, String> getDetailsMap() { return this.detailsMap; }
@@ -27,6 +28,8 @@ public class Record { | |||
|
|||
private String stringAttribute; | |||
|
|||
private Map<String, String> attributesMap; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a generic question - not specifically related to this line only.
We are only supporting maps of <String, String> with this change right?
How could we extend this to support different value types long term - at minimum I'd think the standard types we support, potentially even allowing custom attribute converters to be applied.
I think releasing this with only String values is probably reasonable, but I want to make sure that we could add more support in the future without it being a breaking change.
Added the facility of using an annotation that will flatten a map of attributes in a class,
similar to what @DynamoDbFlatten does for attributes from another class.
Description
Added a new annotation named DynamoDbFlattenMap that can be applied at method level for only a single map of attributes within a class (Map<String, String>). If used on multiple maps of attributes, the serialization will throw an exception.
Motivation and Context
#2542
Modifications
Followed the same approach as for DybamoDbFlatten annotation, that is used to flatten all the attributes of a separate DynamoDb bean that is stored in the current bean
Testing
The changes have already been tested by running the existing tests and also added new unit/integration tests for the new flow.
Test Coverage Checklist
Screenshots (if appropriate)
Types of changes
Checklist
mvn install
succeedsscripts/new-change
script and following the instructions. Commit the new file created by the script in.changes/next-release
with your changes.License